﻿using Sprout.Schedule.Daos;
using Sprout.Schedule.Dtos;
using Sprout.Schedule.Enums;
using Sprout.Schedule.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Sprout.Core.Extensions;
using Quartz;
using Microsoft.Extensions.Logging;
using Sprout.Core;

namespace Sprout.Schedule.Services
{
    public class TaskService : ITaskService
    {
        Lazy<ITaskDao> taskDao = ServiceLocator.GetLazyService<ITaskDao>();
        Lazy<ITaskLogService> taskLogService = ServiceLocator.GetLazyService<ITaskLogService>();

        #region 异步 
        /// <summary>
        /// 新增任务
        /// </summary>
        /// <param name="dto"></param>
        /// <returns>主键ID</returns>
        public async Task<long> Insert(TaskInfo dto)
        {
            if (string.IsNullOrEmpty(dto.CronExpression) || !CronExpression.IsValidExpression(dto.CronExpression))
            {
                throw new Exception("无效的Cron表达式。");
            }
            dto.Parameters = dto.Parameters.ToEmptyAndTrim();
            dto.JobFullName = dto.JobFullName.ToEmptyAndTrim();
            dto.Remark = dto.Remark.ToEmptyAndTrim();
            dto.RunValue = dto.RunValue.ToEmptyAndTrim();
            dto.IsDeleted = false;
            dto.RunStatus = TaskRunStatusEnum.Stop;
            dto.CreateTime = DateTime.Now;
            dto.UpdateTime = dto.CreateTime;

            return await taskDao.Value.InsertAsync(dto);
        }

        /// <summary>
        /// 删除任务
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task Delete(long id)
        {
            await taskDao.Value.DeleteAsync(new TaskInfo() { Id = id, UpdateTime = DateTime.Now });
        }
        /// <summary>
        /// 查询详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<TaskInfo> GetDetailAsync(long id)
        {
            return await taskDao.Value.GetDetailAsync(new TaskQuery() { Id = id });
        }
        /// <summary>
        /// 查询任务列表
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<IList<TaskInfo>> Gets(TaskQuery query)
        {
            return await taskDao.Value.GetsAsync(query);
        }

        /// <summary>
        /// 修改任务
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task Update(TaskInfo dto)
        {
            if (string.IsNullOrEmpty(dto.CronExpression) || !CronExpression.IsValidExpression(dto.CronExpression))
            {
                throw new Exception("无效的Cron表达式。");
            }
            dto.Parameters = dto.Parameters.ToEmptyAndTrim();
            dto.JobFullName = dto.JobFullName.ToEmptyAndTrim();
            dto.Remark = dto.Remark.ToEmptyAndTrim();
            dto.RunValue = dto.RunValue.ToEmptyAndTrim();

            dto.UpdateTime = DateTime.Now;
            await taskDao.Value.UpdateAsync(dto);
        }

        /// <summary>
        /// 修改任务状态
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="status">状态</param>
        /// <returns></returns>
        public async Task UpdateStatus(long id, TaskStatusEnum status)
        {

            await taskDao.Value.UpdateStatusAsync(new TaskInfo()
            {
                Id = id,
                Status = status,
                UpdateTime = DateTime.Now
            });
        }

        /// <summary>
        /// 任务开始运行
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task RunAsync(long id)
        {
            DateTime now = DateTime.Now;
            var rowCount = await taskDao.Value.RunAsync(new TaskInfo()
            {
                Id = id,
                RunTime = now,
                UpdateTime = now
            });
            if (rowCount == 0)
            {
                throw new Exception("任务并未处于未运行状态");
            }
        }
        /// <summary>
        /// 任务运行结束
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task RunEndAsync(long id)
        {
            DateTime now = DateTime.Now;
            var rowCount = await taskDao.Value.RunEndAsync(new TaskInfo()
            {
                Id = id,
                RunEndTime = now,
                UpdateTime = now
            });
            if (rowCount == 0)
            {
                throw new Exception("任务并未在运行中");
            }

        }

        /// <summary>
        /// 修改最后执行的值
        /// </summary>
        /// <param name="id"></param>
        /// <param name="runValue"></param>
        /// <returns></returns>
        public async Task UpdateRunValueAsync(long id, string runValue)
        {
            DateTime now = DateTime.Now;
            var rowCount = await taskDao.Value.UpdateRunValueAsync(new TaskInfo()
            {
                Id = id,
                UpdateTime = now,
                RunValue = runValue
            });
            if (rowCount == 0)
            {
                throw new Exception("修改失败，可能是任务ID传入异常");
            }
        }

        /// <summary>
        /// 中止任务
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task Interrupt(long id)
        {
            DateTime now = DateTime.Now;
            var rowCount = await taskDao.Value.RunEndAsync(new TaskInfo()
            {
                Id = id,
                RunEndTime = now,
                UpdateTime = now
            });
            if (rowCount == 0)
            {
                throw new Exception("任务并未在运行中");
            }
            await taskLogService.Value.LogAsync(id, "强制中止任务");
        }
        #endregion

        #region 同步

        /// <summary>
        /// 任务开始运行
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public void Run(long id)
        {
            DateTime now = DateTime.Now;
            var rowCount = taskDao.Value.Run(new TaskInfo()
            {
                Id = id,
                RunTime = now,
                UpdateTime = now
            });
            if (rowCount == 0)
            {
                throw new Exception("任务并未处于未运行状态");
            }
        }
        /// <summary>
        /// 任务运行结束
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public void RunEnd(long id)
        {
            DateTime now = DateTime.Now;
            var rowCount = taskDao.Value.RunEnd(new TaskInfo()
            {
                Id = id,
                RunEndTime = now,
                UpdateTime = now
            });
            if (rowCount == 0)
            {
                throw new Exception("任务并未在运行中");
            }

        }

        /// <summary>
        /// 修改最后执行的值
        /// </summary>
        /// <param name="id"></param>
        /// <param name="runValue"></param>
        /// <returns></returns>
        public void UpdateRunValue(long id, string runValue)
        {
            DateTime now = DateTime.Now;
            var rowCount = taskDao.Value.UpdateRunValue(new TaskInfo()
            {
                Id = id,
                UpdateTime = now,
                RunValue = runValue
            });
            if (rowCount == 0)
            {
                throw new Exception("修改失败，可能是任务ID传入异常");
            }
        }

        /// <summary>
        /// 查询详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TaskInfo GetDetail(long id)
        {
            return taskDao.Value.GetDetail(new TaskQuery() { Id = id });
        }
        #endregion
    }
}
